﻿using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Http;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.Logging;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace Api
{ 
    public class CustomErrorPagesMiddleware
    {
        private readonly RequestDelegate _next;
        private readonly ILogger _logger;
        private readonly IConfiguration _config;

        public CustomErrorPagesMiddleware(
            RequestDelegate next,
            ILoggerFactory loggerFactory, IConfiguration configuration)
        {
            _next = next;
            _logger = loggerFactory.CreateLogger<CustomErrorPagesMiddleware>();
            _config = configuration;
        }

        public async Task Invoke(HttpContext context)
        {
            Exception exout = null;
            try
            {
                context.Response.Headers.Add("Access-Control-Expose-Headers", "Content-Disposition");
                await _next(context);
            }
            catch (Exception ex)
            {
                exout = ex;
                _logger.LogError(0, ex, "An unhandled exception has occurred while executing the request");

                if (context.Response.HasStarted)
                {
                    _logger.LogWarning("The response has already started, the error page middleware will not be executed.");
                    throw;
                }
                try
                {
                    context.Response.Clear();
                    context.Response.StatusCode = 500;
                    return;
                }
                catch (Exception ex2)
                {
                    _logger.LogError(0, ex2, "An exception was thrown attempting to display the error page.");
                }
                throw;
            }
            finally
            {
                var statusCode = context.Response.StatusCode;
                if (statusCode == 404 || statusCode == 500)
                {

                    await ErrorPage.ResponseAsync(context.Response, statusCode, exout, _config["errorPage"].ToString());
                }
            }
        }
    }
    public class ErrorPage
    {
         
   
        public static async Task ResponseAsync(HttpResponse response, int statusCode, Exception ex,string errorPage)
        {
            if (statusCode == 404)
            {
                if (response.HttpContext.Request.Path == "/")
                {
                    response.Redirect("/api/values");
                }
                var result = new { code = 1, msg = "404 NoFound" };
                response.StatusCode = 666;
                await response.WriteAsync(Newtonsoft.Json.JsonConvert.SerializeObject(result));
            }
            else if (statusCode == 500)
            { 
                response.ContentType = "text/plain; charset=utf-8";
                var result = new { code = 1, msg = ex.GetType().Name + "==>" + ex.Message, data = ex.StackTrace };
                response.StatusCode = 666;
                await response.WriteAsync(Newtonsoft.Json.JsonConvert.SerializeObject(result));
            }
        } 
    }
    public static class CustomErrorPagesExtensions
    {
        public static IApplicationBuilder UseCustomErrorPages(this IApplicationBuilder app)
        {
            if (app == null)
            {
                throw new ArgumentNullException(nameof(app));
            }

            return app.UseMiddleware<CustomErrorPagesMiddleware>();
        }
    }
}
